package com.enjoy.xbase.qk.task;

import android.util.Log;

import com.alibaba.fastjson.JSON;
import com.enjoy.xbase.qk.bean.ERR;
import com.enjoy.xbase.qk.impi.RequestBack;
import com.enjoy.xbase.qk.impi.RequestInfo;
import com.enjoy.xbase.qk.model.CommonModel;

import java.io.File;
import java.io.IOException;
import java.util.Map;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * Created by cxb on 2018/6/25.
 */

public class PutTask extends BaseTask {
    private CommonModel commonModel;
    private RequestInfo requestInfo;

    public PutTask(CommonModel commonModel, RequestBack back, RequestInfo requestInfo) {
        super(commonModel, back, requestInfo);
        this.requestInfo = requestInfo;
        this.commonModel = commonModel;
    }

    public void run() {
        if (commonModel.getTag() != null && !"".equals(commonModel.getTag())) {
            try {
                Thread.sleep(commonModel.getWaitTime());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (!requestInfo.isLast(commonModel.getTag(), commonModel.getRequestTime())) return;
        }
        Log.i(commonModel.getUrl(), "POST请求数据:" + commonModel.getParameter_obj().toString() + "");

        okhttp3.Request.Builder builder = new okhttp3.Request.Builder()
                .url(commonModel.getUrl())
                .put(getRequestBody())
                .tag(commonModel.getTagId() == null ? "" : commonModel.getTagId());
        for (Map.Entry<String, String> header : commonModel.getHeaders().entrySet()) {
            if (header != null) {
                builder.addHeader(header.getKey(), header.getValue());
            }
        }
        okhttp3.Request request = builder.build();
        OkHttpClient client;
        if (hasFile()) {//创建OkHttpClient对象。
            client = requestInfo.getUpFileClient();
        } else {
            client = requestInfo.getClient();
        }
        Call call = client.newCall(request);
        requestInfo.addCall(call);

        //execute的方法是同步方法，
        //enqueue的方法是异步方法，

        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                requestInfo.removeCall(call);
                if (call.isCanceled()) {//关闭界面的取消请求执行这里
                    setBackCancel();
                } else {
                    setBackFail(ERR.ERR_NET);
                }
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                requestInfo.removeCall(call);
                //回调的方法执行在子线程。
                Log.d("net", "获取数据成功了");
                Log.d("net", "response.code()==" + response.code());
                try {
                    setResultData(response.body().string());
                } catch (IOException e) {
                    setBackFail(ERR.ERR_NET);
                    Log.d("net", "网络异常中断");
                }
            }
        });
    }

    public RequestBody getRequestBody() {
        if (hasFile()) {
            return getMultipartBody();
        } else if (commonModel.getContentType() == CommonModel.ContentType.json) {
            return getJsonBody();
        } else {
            return getFormBody();
        }
    }

    public FormBody getFormBody() {
        FormBody.Builder builder = new FormBody.Builder();//创建表单请求体
        for (Map.Entry<String, Object> itemFile : commonModel.getParameter_obj().entrySet()) {
            if (itemFile != null) {
                String key = itemFile.getKey();
                Object value = itemFile.getValue();
                builder.add(key, value + "");//传递键值对参数
            }
        }
        FormBody formBody = builder.build();
        return formBody;
    }

    public RequestBody getJsonBody() {
        String content;
        if (commonModel.getContent() != null) {
            content = JSON.toJSONString(commonModel.getContent());
        } else {
            content = JSON.toJSONString(commonModel.getParameter_obj());
        }
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), content);
        return requestBody;
    }


    public MultipartBody getMultipartBody() {
        MultipartBody.Builder multipartBody = new MultipartBody.Builder();
        multipartBody.setType(MultipartBody.FORM);
        for (Map.Entry<String, Object> itemFile : commonModel.getParameter_obj().entrySet()) {
            if (itemFile != null) {
                String key = itemFile.getKey();
                Object value = itemFile.getValue();
                if (isPrimitive(value)) {
                    multipartBody.addFormDataPart(key, value + "");//传递键值对参数
                } else {
                    RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), JSON.toJSONString(value));
                    multipartBody.addFormDataPart(key, "jsondata", requestBody);
                }
            }
        }
        for (Map.Entry<String, File> itemFile : commonModel.getParameter_file().entrySet()) {
            if (itemFile != null) {
                String key = itemFile.getKey();
                File file = itemFile.getValue();
                multipartBody.addFormDataPart(key, file.getName(), RequestBody.create(MediaType.parse("file/*"), file));//添加文件
            }
        }
        return multipartBody.build();
    }

    private boolean isPrimitive(Object obj) {
        boolean baseType;
        try {
            baseType = ((Class<?>) obj.getClass().getField("TYPE").get(null)).isPrimitive();
        } catch (Exception e) {
            baseType = false;
        }
        if (baseType) {
            return true;
        } else if (obj instanceof String) {
            return true;
        }
        return false;
    }

    private boolean hasFile() {
        if (commonModel.getParameter_file().size() > 0) {
            return true;
        }
        return false;
    }

}
